package com.doudoukeji.service.Utils;

import android.app.AlertDialog;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.doudoukeji.service.Activity.ConstantValue;
import com.doudoukeji.service.Activity.GlobalParams;
import com.doudoukeji.service.R;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * 捕获全局异常,因为有的异常我们捕获不到
 *
 * @author river
 */
public class UncaughtException implements UncaughtExceptionHandler {
    private final static String TAG = "UncaughtException";
    private static String path = Environment.getExternalStorageDirectory()
            + "/ahb/crash/";

    private static UncaughtException mUncaughtException;
    private Context context;
    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
    private StringBuffer sb;
    private SimpleDateFormat format = new SimpleDateFormat(
            "yyyy-MM-dd-HH-mm-ss");
    private String time;
    private String md5str = "imatesclubsalt";

    public static final String SERVICE_CLASSNAME = "com.imatesclub.service.MQTTService";

    // 用来存储设备信息和异常信息
    private Map<String, String> infos = new HashMap<String, String>();

    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    private UncaughtException() {
        // TODO Auto-generated constructor stub
    }

    /**
     * 同步方法，以免单例多线程环境下出现异常
     *
     * @return
     */
    public synchronized static UncaughtException getInstance() {
        if (mUncaughtException == null) {
            mUncaughtException = new UncaughtException();
        }
        return mUncaughtException;
    }

    /**
     * 初始化，把当前对象设置成UncaughtExceptionHandler处理器
     */
    public void init() {
        Thread.setDefaultUncaughtExceptionHandler(mUncaughtException);
    }

    private boolean isShow = true;
    private GlobalParams helper;

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        helper = (GlobalParams) context.getApplicationContext();
        if (isShow) {
            collectDeviceInfo(context);
            saveCrashInfo2File(ex);
            showDialog();
        } else {
        }
    }

    private void showDialog() {
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();

                View view = View.inflate(context, R.layout.exception_dialog, null);
                Button button = (Button) view
                        .findViewById(R.id.dialog_button_cancel);

                Button button1 = (Button) view
                        .findViewById(R.id.dialog_button_ok);

                final AlertDialog dlg = new AlertDialog.Builder(context)
                        .setCancelable(false).create();

                dlg.setView(view, 0, 0, 0, 0);
                button.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {

//
//                        HttpClientUtil util = new HttpClientUtil();
//                        Map<String, String> map = new HashMap<String, String>();
//
//
//                        TelephonyManager tm = (TelephonyManager) context
//                                .getSystemService(Context.TELEPHONY_SERVICE);
//                        String imei = tm.getDeviceId();
//                        md5str = imei + md5str;
//                        String md5 = MD5(md5str);
//
//                        map.put("err_des", sb.toString());
//                        map.put("device_number", imei);
//                        map.put("token", md5);
//
//                        String post = util.sendPostPhp(
//                                ConstantValue.BugUrl, map);
//                        isShow = true;
//                        Intent startMain = new Intent(Intent.ACTION_MAIN);
//                        startMain.addCategory(Intent.CATEGORY_HOME);
//                        startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//                        context.startActivity(startMain);
//                        String third_party_login = SharedPreferencesUtils.getParam(context, "third_party_login", "0");
//                        if ("1".equals(third_party_login)) {
////							LoginTabActivity.mTencent.logout(context);
//                            SharedPreferencesUtils.setParam(context, "third_party_login",
//                                    "0");
//                        }
//                        DataCleanManager.cleanExternalCache(context);
//                        DataCleanManager.cleanInternalCache(context);
//                        helper.exit();
//                        System.exit(0);
                    }
                });


                button1.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {


//                        HttpClientUtil util = new HttpClientUtil();
//                        Map<String, String> map = new HashMap<String, String>();
//
//
//                        LogUtil.info("bug信息====" + sb.toString(), ConstantValue.currentStage);
//                        TelephonyManager tm = (TelephonyManager) context
//                                .getSystemService(Context.TELEPHONY_SERVICE);
//                        String imei = tm.getDeviceId();
//                        md5str = md5str + imei;
//                        String md5 = MD5(md5str);
//
//                        map.put("err_des", sb.toString());
//                        map.put("device_number", imei);
//                        map.put("token", md5);
//
//                        String post = util.sendUnDESPost(
//                                ConstantValue.BugUrl, map);
//                        LogUtil.info("bug反馈====" + post, ConstantValue.currentStage);
//                        isShow = true;
//                        Intent startMain = new Intent(Intent.ACTION_MAIN);
//                        startMain.addCategory(Intent.CATEGORY_HOME);
//                        startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//                        context.startActivity(startMain);
//                        helper.exit();
//                        System.exit(0);
                    }
                });

                dlg.show();
                Looper.loop();
            }
        }.start();
    }


    // MD5加密，32位
    public static String MD5(String str) {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

        char[] charArray = str.toCharArray();
        byte[] byteArray = new byte[charArray.length];

        for (int i = 0; i < charArray.length; i++) {
            byteArray[i] = (byte) charArray[i];
        }
        byte[] md5Bytes = md5.digest(byteArray);

        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }

    /**
     * 收集设备参数信息
     *
     * @param context
     */
    public void collectDeviceInfo(Context context) {
        isShow = false;
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(),
                    PackageManager.GET_ACTIVITIES);
            if (pi != null) {
                String versionName = pi.versionName == null ? "null"
                        : pi.versionName;
                String versionCode = pi.versionCode + "";
                infos.put("versionName", versionName);
                infos.put("versionCode", versionCode);
            }
        } catch (NameNotFoundException e) {
            Log.e(TAG, "an error occured when collect package info", e);
        }
        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                if ("TIME".equals(field.getName())) {
                    time = format.format(new Date());
                    infos.put(field.getName(), time);
                } else {
                    infos.put(field.getName(), field.get(null).toString());
                }
                Log.d(TAG, field.getName() + " : " + field.get(null));
            } catch (Exception e) {
                Log.e(TAG, "an error occured when collect crash info", e);
            }
        }
    }

    /**
     * 保存错误信息到文件中 *
     *
     * @param ex
     * @return 返回文件名称, 便于将文件传送到服务器
     */
    private String saveCrashInfo2File(Throwable ex) {


        String SDState = Environment.getExternalStorageState();
        if (SDState.equals(Environment.MEDIA_MOUNTED)) {
            sb = new StringBuffer();
            for (Map.Entry<String, String> entry : infos.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                sb.append(key + "=" + value + "\n");
            }

            Writer writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter(writer);
            ex.printStackTrace(printWriter);
            Throwable cause = ex.getCause();
            while (cause != null) {
                cause.printStackTrace(printWriter);
                cause = cause.getCause();
            }
            printWriter.close();
            String result = writer.toString();
            sb.append(result);
            try {
                long timestamp = System.currentTimeMillis();
                String time = format.format(new Date());
                String fileName = "crash-" + time + "-" + timestamp + ".txt";
                if (Environment.getExternalStorageState().equals(
                        Environment.MEDIA_MOUNTED)) {
                    File dir = new File(path);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    FileOutputStream fos = new FileOutputStream(path + fileName);
                    fos.write(sb.toString().getBytes());
                    LogUtil.info(sb.toString() + "===============", ConstantValue.currentStage);
                    fos.close();
                }
                return fileName;
            } catch (Exception e) {
                Log.e(TAG, "an error occured while writing file...", e);
            }
        }
        return null;

    }
}
